package com.gf.user.controller;

import java.io.File;
import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.gf.base.controller.BasicController;
import com.gf.base.type.BloodType;
import com.gf.base.type.EventType;
import com.gf.base.type.ExamType;
import com.gf.base.type.FileType;
import com.gf.base.type.OperationType;
import com.gf.base.type.Role;
import com.gf.base.type.Sex;
import com.gf.common.bean.DataRequest;
import com.gf.common.bean.DataResponse;
import com.gf.common.bean.Page;
import com.gf.common.constant.Constants;
import com.gf.common.constant.ViewPaths;
import com.gf.common.staticer.AllNicknamesAndUID;
import com.gf.common.staticer.MessageRemainsHelper;
import com.gf.common.util.FileHelper;
import com.gf.common.util.WebHelper;
import com.gf.event.service.EventService;
import com.gf.exam.service.ExamCellService;
import com.gf.fund.service.FundService;
import com.gf.message.service.MessageService;
import com.gf.user.model.Suggestion;
import com.gf.user.model.User;
import com.gf.user.service.IdolFanService;
import com.gf.user.service.UploadFileRecordService;
import com.gf.user.service.UserBaseService;
import com.gf.user.service.UserService;

/**
 * 用户操作<br>
 * 登入个人主页、修改密码等
 * 
 * @author zhuguifeng
 * 
 */

@Controller
@RequestMapping(value = "/user")
public class UserController extends BasicController {

	private static final Log logger = LogFactory.getLog(UserController.class);

	@Autowired
	private UserBaseService userBaseService;
	@Autowired
	private UserService userService;
	@Autowired
	private FundService fundService;
	@Autowired
	private IdolFanService idolFanService;
	@Autowired
	private MessageService messageService;
	@Autowired
	private EventService eventService;
	@Autowired
	private ExamCellService examCellService;

	@Autowired
	private UploadFileRecordService uploadFileRecordService;

	/**
	 * 查看其他用户
	 * 
	 * @return
	 */
	@RequestMapping(value = "/other", method = RequestMethod.GET)
	public ModelAndView viewOtherUserHome(long otherId) {
		User loginUser = WebHelper.getSessionUser();

		ModelAndView mvc = new ModelAndView();
		// 判断要浏览的是不是用户本身
		if (loginUser.getId() == otherId) {
			mvc.setViewName("redirect:" + ViewPaths.HOME_VIEW
					+ ViewPaths.SUFFIX);
			return mvc;
		}

		User userToView = userService.getUserById(otherId);
		long userId = userToView.getId();

		long idoCount = idolFanService.getIdolNumber(userId);
		long ifunCount = idolFanService.getFanNumber(userId);
		// 显示的还是自己的消息
		int messageCount = MessageRemainsHelper.getRemains(loginUser.getId());

		int pptCount = 0;
		// 普通用户是参与
		if (userToView.getRole().toString().equals(Role.NORMAL.toString())) {
			pptCount = examCellService.getJoinNumberByUserId(userId);
		} else {
			pptCount = examCellService.getTotal(userId, ExamType.PUBLIC);
		}

		mvc.addObject("idolCount", idoCount);
		mvc.addObject("fanCount", ifunCount);
		mvc.addObject("messageCount", messageCount);
		// 为安全地起见，密码为空
		userToView.setPassword("");
		mvc.addObject("other", userToView);
		mvc.addObject("user", loginUser);
		mvc.addObject("pptCount", pptCount);
		mvc.setViewName(ViewPaths.HOME_OTHER_VIEW);

		return mvc;
	}

	/**
	 * 个人设置
	 * 
	 * @return
	 */
	@RequestMapping(value = "/setup", method = RequestMethod.GET)
	public ModelAndView setup() {
		User user = WebHelper.getSessionUser();
		ModelAndView mvc = new ModelAndView();

		if (user != null) {
			int messageCount = MessageRemainsHelper.getRemains(user.getId());
			mvc.addObject("messageCount", messageCount);
		}

		mvc.setViewName(ViewPaths.SETUP_VIEW);
		mvc.addObject("user", user);

		return mvc;

	}

	/**
	 * 关注
	 * 
	 * @return
	 */
	@RequestMapping(value = "/care", method = RequestMethod.GET)
	public ModelAndView care() {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		ModelAndView mvc = new ModelAndView();
		mvc.setViewName(ViewPaths.FANS_CARE);
		user = userBaseService.getUserById(user.getId());
		mvc.addObject("careCount", user.getCareCount());
		return mvc;
	}

	/**
	 * 粉丝
	 * 
	 * @return
	 */
	@RequestMapping(value = "/fans", method = RequestMethod.GET)
	public ModelAndView fans() {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		ModelAndView mvc = new ModelAndView();
		mvc.setViewName(ViewPaths.FANS_FANS);
		user = userBaseService.getUserById(user.getId());
		mvc.addObject("fansCount", user.getFansCount());
		return mvc;
	}

	/**
	 * 粉丝
	 * 
	 * @return
	 */
	@RequestMapping(value = "/fansindex", method = RequestMethod.GET)
	public ModelAndView fansindex() {
		ModelAndView mvc = new ModelAndView();
		User loginUser = WebHelper.getSessionUser();

		int messageCount = MessageRemainsHelper.getRemains(loginUser.getId());
		mvc.addObject("messageCount", messageCount);
		mvc.setViewName(ViewPaths.FANS_INDEX);
		mvc.addObject("user", loginUser);

		return mvc;
	}

	/**
	 * 更新数据
	 * 
	 * @param sex
	 * @param bloodType
	 * @param income
	 * @param experience
	 * @return
	 */
	@RequestMapping(value = "/setup", method = RequestMethod.POST)
	public @ResponseBody
	boolean setupUpdate(String sex, String bloodType, String income,
			String experience) {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return false;
		}

		boolean result = userService.setupUpdate(user.getId(),
				Sex.valueOf(sex), BloodType.valueOf(bloodType), income,
				experience);

		if (result) {
			user = userService.getUserById(user.getId());
			WebHelper.setSessionAttribute(Constants.SESSION_USER, user);
		}
		return result;
	}

	/**
	 * 登入个人主页
	 * 
	 * @return
	 */
	@RequestMapping(value = "/home", method = RequestMethod.GET)
	public ModelAndView inHome() {
		logger.info("登入个人主页");
		
		//为了让session中的用户与数据库中的session中保持一致
		//每次主页都重新从数据库中取得该用户信息

		ModelAndView mvc = new ModelAndView();
		User user = WebHelper.getSessionUser();
		long userId = user.getId();
		int pptCount = 0;
		// 普通用户是参与
		if (user.getRole().toString().equals(Role.NORMAL.toString())) {
			pptCount = examCellService.getJoinNumberByUserId(userId);
		} else {
			pptCount = examCellService.getTotal(userId, ExamType.PUBLIC);
		}
		int messageCount = MessageRemainsHelper.initLogin(userId);

		double fund = fundService.getTotal(userId);
		mvc.addObject("user", user);
		mvc.addObject("pptCount", pptCount);
		mvc.addObject("messageCount", messageCount);
		mvc.addObject("fund", fund);
		mvc.setViewName(ViewPaths.HOME_VIEW);

		return mvc;
	}

	/**
	 * 修改头像
	 * 
	 * @return
	 */
	@RequestMapping(value = "/updatePortrait", method = RequestMethod.GET)
	public ModelAndView updatePortraitRequest() {
		logger.info("上传头像请求");
		ModelAndView mvc = new ModelAndView();

		mvc.addObject("uploadInfo", "亲,上传头像");
		mvc.setViewName(ViewPaths.UPDATE_PORTRAIT_VIEW);

		return mvc;
	}

	/**
	 * 上传头像
	 * 
	 * @param portraitfile
	 * @return 失败返回error
	 * @throws IOException
	 */
	@RequestMapping(value = "/updatePortrait", method = RequestMethod.POST)
	public void updatePortraitExcute(
			@RequestParam("portraitfile") MultipartFile portraitfile,
			HttpServletResponse response) throws IOException {
		response.setContentType("text/html;charset=utf-8");

		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			String str = "<script type='text/javascript'>window.onload=function(){parent.callback('请先登入','');}</script>";
			response.getWriter().write(str);
		}

		int result = FileHelper.validate(portraitfile, FileType.PORTRAIT);
		if (result == 0) {
			String newPath = FileHelper.savePotrait(portraitfile);
			if (newPath != null) {
				// 删除老头像
				String oldPath = user.getPortrait();
				if (oldPath != null && !oldPath.equals("")) {
					File oldFile = new File(oldPath);
					if (oldFile.isFile()) {
						oldFile.delete();
					}
				}
				// 更新到数据库中
				userService.changeProtrait(user.getId(), newPath);
				eventService.changePortrait(user.getId(), newPath);
				logger.debug("上传头像成功! " + newPath);

				// 更新session
				user = userService.getUserById(user.getId());
				WebHelper.removeSessionAttribute(Constants.SESSION_USER);
				WebHelper.setSessionAttribute(Constants.SESSION_USER, user);

				String str = "<script type='text/javascript'>window.onload=function(){parent.callback('上传成功','"
						+ newPath + "');}</script>";
				response.getWriter().write(str);
				return;
			}
		}
		logger.debug("上传头像失败");
		String str = "<script type='text/javascript'>window.onload=function(){parent.callback('上传失败','');}</script>";
		response.getWriter().write(str);
	}

	/**
	 * 上传执照
	 * 
	 * @param portraitfile
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/uploadLicense", method = RequestMethod.POST)
	public void uploadLicense(
			@RequestParam("licensefile") MultipartFile licensefile,
			HttpServletResponse response) throws IOException {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		response.setContentType("text/html;charset=utf-8");
		if (user == null) {
			logger.debug("木有登入  或者  该用户的身份不是专家");
			String str = "<script type='text/javascript'>window.onload=function(){parent.callback1('您未登入');}</script>";
			response.getWriter().write(str);
			return;
		}

		int result = FileHelper.validate(licensefile, FileType.LICENSE);
		if (result == 0) {
			String newPath = FileHelper.saveLicenceOfDoctor(licensefile);
			if (newPath != null) {
				// 删除老执照
				String oldPath = user.getLicensePath();
				if (oldPath != null && !oldPath.equals("")) {
					File oldFile = new File(oldPath);
					if (oldFile.isFile()) {
						oldFile.delete();
					}
				}
				// 更新到数据库中
				userService.uploadLicense(user.getId(), newPath);
				logger.debug("上传执照成功! " + newPath);

				// 更新session
				user = userService.getUserById(user.getId());
				WebHelper.removeSessionAttribute(Constants.SESSION_USER);
				WebHelper.setSessionAttribute(Constants.SESSION_USER, user);

				String str = "<script type='text/javascript'>window.onload=function(){parent.callback1('上传执照成功');}</script>";
				response.getWriter().write(str);
				return;
			}
		}
		logger.debug("上传执照失败");
		String str = "<script type='text/javascript'>window.onload=function(){parent.callback1('上传执照失败');}</script>";
		response.getWriter().write(str);
	}

	/**
	 * 得到头像的路径
	 * 
	 * @return
	 */
	@RequestMapping(value = "getPortrait", method = RequestMethod.POST)
	public @ResponseBody
	String getPortrait() {
		logger.debug("得到头像的路径");
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return "";
		}
		return userService.getProtrait(user.getId());
	}

	/**
	 * 上传文件并存储<br>
	 * 上传成功后其相对地址保存在session里
	 * 
	 * @param imagefile
	 * @param type
	 *            得到上传的文件类型
	 * @return 成功
	 * @throws IOException
	 */
	@RequestMapping(value = "/uploadfile", method = RequestMethod.POST)
	public void uploadFileExcute(
			@RequestParam("uploadFile") MultipartFile inputFile, String type,
			HttpServletResponse response) throws IOException {

		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			response.setContentType("text/html;charset=utf-8");
			String str = "<script type='text/javascript'>window.onload=function(){parent.callback('请登入','','');}</script>";
			response.getWriter().write(str);
			return;
		}

		logger.debug("上传文件类型：" + type + "  文件名："
				+ inputFile.getOriginalFilename());

		// 验证:包括类型 大小
		int result = FileHelper.validate(inputFile, FileType.valueOf(type));
		response.setContentType("text/html;charset=utf-8");

		if (result == 0) {
			String newFilepath = "";
			if (FileType.ID_CARD.toString().equals(type)) {
				newFilepath = FileHelper.saveIdCard(inputFile);
			} else if (FileType.LICENSE.toString().equals(type)) {
				newFilepath = FileHelper.saveLicenceOfDoctor(inputFile);
			} else if (FileType.IMAGE.toString().equals(type)) {
				newFilepath = FileHelper.saveImage(inputFile);
			} else if (FileType.MEDIA.toString().equals(type)) {
				newFilepath = FileHelper.saveMedia(inputFile);
			} else if (FileType.FLASH.toString().equals(type)) {
				newFilepath = FileHelper.saveFlash(inputFile);
			} else if (FileType.VOICE.toString().equals(type)) {
				newFilepath = FileHelper.saveVoice(inputFile);
			} else if (FileType.VIDEO.toString().equals(type)) {
				newFilepath = FileHelper.saveVideo(inputFile);
			}

			// 存储成功
			if (newFilepath != null && !newFilepath.equals("")) {
				// 将上传记录写入到数据库中
				uploadFileRecordService.saveUploadRecored(user.getId(),
						newFilepath, FileType.valueOf(type));

				// 存入session
				if (FileType.ID_CARD.toString().equals(type)) {
					WebHelper.setSessionAttribute(
							Constants.SESSION_ID_CARD_PATH, newFilepath);
				} else if (FileType.LICENSE.toString().equals(type)) {
					WebHelper.setSessionAttribute(
							Constants.SESSION_LICENCE_PATH, newFilepath);
				}

				String str = "<script type='text/javascript'>window.onload=function(){parent.callback('上传成功','../"
						+ newFilepath + "','" + type + "');}</script>";
				response.getWriter().write(str);
				return;

				// 以上的为swfupload的返回格式 以下的是在exam中kindeditor下上传文件的接口
				// JSONObject object = new JSONObject();
				// object.put("error", 0);
				// object.put("url", "../" + newFilepath);
				// response.getWriter().write(object.toString());
			}
		}
		// 上传出错
		String str = "<script type='text/javascript'>window.onload=function(){parent.callback('上传失败','','');}</script>";
		response.getWriter().write(str);

		// if (FileType.ID_CARD.toString().endsWith(type)
		// || FileType.LICENSE.toString().equals(type)) {
		// response.getWriter().write("上传失败");
		// return;
		// }
		// // exam里要求返回的格式
		// else {
		// JSONObject obj = new JSONObject();
		// obj.put("error", 1);
		// obj.put("message", "上传失败");
		// response.getWriter().write(obj.toString());
		// return;
		// }

	}

	/**
	 * 用户昵称自己匹配与提醒
	 * 
	 * @param query
	 *            关键字
	 * @return
	 */
	@RequestMapping(value = "/nickname/getSuggestion", method = RequestMethod.POST)
	public @ResponseBody
	Suggestion getNicknameSuggestion(String query) {
		// 用户需要登入
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return null;
		}

		logger.info("昵称 suggestion:query->" + query);

		// 对query进行处理:41387327@qq.com;173779
		// 此时query 处理后=173779
		// 存在多个联系人,返回最后一个
		int index = -1;
		if ((index = query.lastIndexOf(";")) != -1) {
			query = query.substring(index + 1);
		}

		return AllNicknamesAndUID.query(query);

	}

	/**
	 * 用户更新用户信息请求
	 * 
	 * @return
	 */
	@RequestMapping(value = "/info", method = RequestMethod.GET)
	public ModelAndView updateUserInfo() {
		User user = WebHelper.getSessionUser();

		ModelAndView mvc = new ModelAndView();
		mvc.setViewName(ViewPaths.USER_INFO);
		mvc.addObject("user", user);

		return mvc;
	}

	/**
	 * 检查密码是否正确
	 * 
	 * @param password
	 * @return
	 */
	@RequestMapping(value = "/checkPassword", method = RequestMethod.POST)
	public @ResponseBody
	boolean checkPassword(String password) {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return false;
		}
		String pass = user.getPassword();
		if (pass.equals(password)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 修改密码
	 * 
	 * @param password
	 */
	@RequestMapping(value = "/modifyPassword", method = RequestMethod.POST)
	public @ResponseBody
	void modifyPassword(String password) {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return;
		}

		userBaseService.modifyPasswd(user.getId(), password);
	}

	/**
	 * 发送验证码
	 * 
	 * @param mobile
	 * @return
	 */
	@RequestMapping(value = "/sendMobileCode", method = RequestMethod.POST)
	public @ResponseBody
	long sendMobileCode(String mobile) {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return -1;
		}
		logger.info(user.getNickname() + "绑定手机");

		// return userService.sendMobileCode(user.getId(), mobile);
		return 1;

	}

	/**
	 * 验证 验证码 是否合法
	 * 
	 * @param code
	 * @return
	 */
	@RequestMapping(value = "/verifyMobileCode", method = RequestMethod.POST)
	public @ResponseBody
	boolean verifyMobileCode(String mobileCode) {
		logger.info("验证 手机验证码:" + mobileCode);

		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return false;
		}

		return userService.verifyMobileCode(user.getId(), mobileCode);

	}

	/**
	 * 关注某人
	 * 
	 * @param idolId
	 * @return
	 */
	@RequestMapping(value = "/addIdol", method = RequestMethod.POST)
	public @ResponseBody
	boolean addIdol(long idolId) {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return false;
		}

		int result = idolFanService.addIdol(user.getId(), idolId);
		User idol = userBaseService.getUserById(idolId);
		if (result == 1) {
			eventService.addEvent(user.getId(), user.getNickname(),
					OperationType.GUAN_ZHU, idol.getNickname(), idolId,
					EventType.ATTENTION);
			// 用户关注成功后，更新session中user的关注数 +1
			user.setCareCount(user.getCareCount() + 1);
			WebHelper.setSessionAttribute(Constants.SESSION_USER, user);
		}

		return result == 1 ? true : false;
	}

	/**
	 * 取消关注某人
	 * 
	 * @param idolId
	 * @return
	 */
	@RequestMapping(value = "/deleteIdol", method = RequestMethod.POST)
	public @ResponseBody
	boolean deleteIdol(long idolId) {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return false;
		}
		int result = idolFanService.deleteIdol(user.getId(), idolId);

		if (result == 1) {
			// 用户关注成功后，更新session中user的关注数 -1
			user.setCareCount(user.getCareCount() - 1);
			WebHelper.setSessionAttribute(Constants.SESSION_USER, user);
		}

		return result == 1 ? true : false;
	}

	/**
	 * 是否已经关注了该用户
	 * 
	 * @param idolId
	 * @return
	 */
	@RequestMapping(value = "/isYourIdol", method = RequestMethod.POST)
	public @ResponseBody
	boolean isYourIdol(long idolId) {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return false;
		}

		return idolFanService.isYourIdol(user.getId(), idolId);
	}

	/**
	 * 本人和其他用户的关系<br>
	 * -1:无登入<br>
	 * 0: 两者没有关系<br>
	 * 1: 本人已关注该用户<br>
	 * 2: 该用户已关注本人<br>
	 * 3: 双方已互相关注
	 * 
	 * @param otherId
	 * @return
	 */
	@RequestMapping(value = "/relationship", method = RequestMethod.POST)
	public @ResponseBody
	int relationship(long otherId) {
		int result = -1;
		User own = WebHelper.getSessionUser();
		if (own == null) {
			return result;
		}
		// 该用户是你的粉丝
		boolean flag1 = idolFanService.isYourFan(own.getId(), otherId);
		boolean flag2 = idolFanService.isYourIdol(own.getId(), otherId);
		if (flag1 && flag2) {
			result = 3;
		} else if (!flag1 && flag2) {
			result = 1;
		} else if (flag1 && !flag2) {
			result = 2;
		} else {
			result = 0;
		}

		return result;
	}

	/**
	 * 取得自己关注的所有的人
	 * 
	 * @return
	 */
	@RequestMapping(value = "/getAllMyIdols", method = RequestMethod.POST)
	public @ResponseBody
	DataResponse getAllMyIdols(DataRequest dataRequest) {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return new DataResponse();
		}

		int curpage = dataRequest.getPage();
		int pageSize = dataRequest.getRows();
		long userId = user.getId();

		Page page = idolFanService.getIdolByUserId(userId, curpage, pageSize);
		DataResponse dataResponse = new DataResponse();
		dataResponse.setResult(page.getResults());
		dataResponse.setPage(page.getCurpage());
		dataResponse.setRecords(page.getTotal());
		dataResponse.setTotal(page.getTotalPage());

		return dataResponse;

	}

	/**
	 * 取得自己的粉丝
	 * 
	 * @return
	 */
	@RequestMapping(value = "/getAllMyFans", method = RequestMethod.POST)
	public @ResponseBody
	DataResponse getAllMyFans(DataRequest dataRequest) {
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user == null) {
			return new DataResponse();
		}

		int curpage = dataRequest.getPage();
		int pageSize = dataRequest.getRows();
		long userId = user.getId();

		Page page = idolFanService.getFanByUserId(userId, curpage, pageSize);
		DataResponse dataResponse = new DataResponse();
		dataResponse.setResult(page.getResults());
		dataResponse.setPage(page.getCurpage());
		dataResponse.setRecords(page.getTotal());
		dataResponse.setTotal(page.getTotalPage());

		return dataResponse;

	}

}
